﻿using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Sgr.EntityFrameworkCore.ValueConversion;

namespace Microsoft.EntityFrameworkCore
{
    /// <summary>
    /// ModelBuilder 扩展：全局统一 DateTime / DateTime? 为 UTC 存取
    /// </summary>
    public static class ModelBuilderUtcExtensions
    {
        /// <summary>
        /// 为所有实体的 DateTime / DateTime? 属性应用 UTC 值转换器
        /// </summary>
        /// <param name="modelBuilder">模型构造器实例</param>
        /// <param name="treatUnspecifiedAsLocal">
        /// 是否将未指定 Kind (Unspecified) 的时间视为 Local 再转换为 UTC：
        /// false = 直接视为 UTC（仅补 Kind，不做换算）
        /// true  = 当作本地时间再转为 UTC（适用于历史数据原本是本地时间却丢失 Kind 的场景）
        /// </param>
        /// <returns>返回原始 modelBuilder 以便链式调用</returns>
        public static ModelBuilder ApplyUtcDateTimeConverters(this ModelBuilder modelBuilder, bool treatUnspecifiedAsLocal = false)
        {
            ArgumentNullException.ThrowIfNull(modelBuilder);

            // 幂等标记（可选）
            if (modelBuilder.Model.FindAnnotation("UtcDateTimeApplied") != null)
                return modelBuilder;

            ValueConverter dateTimeConverter = treatUnspecifiedAsLocal
                ? new UtcDateTimeUnspecifiedAsLocalDbConverter()
                : new UtcDateTimeDbConverter();

            ValueConverter nullableDateTimeConverter = treatUnspecifiedAsLocal
                ? new UtcNullableDateTimeUnspecifiedAsLocalDbConverter()
                : new UtcNullableDateTimeDbConverter();

            foreach (var entityType in modelBuilder.Model.GetEntityTypes())
            {
                foreach (var property in entityType.GetProperties())
                {
                    if (property.ClrType == typeof(DateTime))
                    {
                        property.SetValueConverter(dateTimeConverter);
                    }
                    else if (property.ClrType == typeof(DateTime?))
                    {
                        property.SetValueConverter(nullableDateTimeConverter);
                    }
                }
            }

            modelBuilder.Model.AddAnnotation("UtcDateTimeApplied", true);
            return modelBuilder;
        }
    }
}